/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#pragma once

#include <基本类型.h>
#include <vector>
#include <nmmintrin.h>

#include "basic_vec.h"


typedef struct {
	float32 r;
	float32 g;
	float32 b;
	float32 a;
}S_RGBA32F;


typedef struct {
	float32 左边;
	float32 顶边;
	float32 宽度;
	float32 高度;
}S_Rectf;


typedef struct {
	float32 点A[2];
	float32 点B[2];
	float32 线宽;
	uint8	颜色[4];
	//cl_mem	Buf;
}S_线;

typedef struct {
	float32 X;
	float32 Y;
}S_2D点;





inline void f_初始化Vec3(vec3* vec, float32 value) {
	vec->x = value; vec->y = value; vec->z = value;
}
inline void f_Vec3(vec3* vec, float32* value) {
	vec->x = value[0]; vec->y = value[1]; vec->z = value[2];
}

inline void f_VecMin(const vec3* vec, vec3* min) {
	//min->x = vec->x < min->x ? vec->x : min->x;
	//min->y = vec->y < min->y ? vec->y : min->y;
	//min->z = vec->z < min->z ? vec->z : min->z;
	__m128 A = _mm_set_ps(vec->x, vec->y, vec->z, 0.0f);
	__m128 B = _mm_set_ps(vec->x, vec->y, vec->z, 0.0f);

	A = _mm_min_ps(A, B);
	min->x = A.m128_f32[0];
	min->y = A.m128_f32[1];
	min->z = A.m128_f32[2];
}
inline void f_VecMax(const vec3* vec, vec3* max) {
	__m128 A = _mm_set_ps(vec->x, vec->y, vec->z, 0.0f);
	__m128 B = _mm_set_ps(vec->x, vec->y, vec->z, 0.0f);

	A = _mm_max_ps(A, B);
	max->x = A.m128_f32[0];
	max->y = A.m128_f32[1];
	max->z = A.m128_f32[2];
	//min->x = vec->x > min->x ? vec->x : min->x;
	//min->y = vec->y > min->y ? vec->y : min->y;
	//min->z = vec->z > min->z ? vec->z : min->z;
}



typedef struct {
	float64 x; float64 y; float64 z; float64 w;
}vec4_64;

inline void f_V3_转_V4(const vec3* v3, vec4* v4) {
	v4->x = v3->x; v4->y = v3->y; v4->z = v3->z; v4->x = 1.0;
}
#define VEC4( x, y, z, w) { (x), (y), (z), (w)}







typedef struct _mat4 {
	vec4 m0, m1, m2, m3;
}mat4;


typedef struct {
	float32 x1; float32 y1; float32 z1; float32 x2; float32 y2; float32 z2; float32 s1; float32 s2;
}vec8;


typedef struct _Float4_64 {
	float64 x,y,z,w;
}float4_64;

typedef struct _Int3_64 {
	int64 x, y, z;
}int3_64;

typedef struct _Int4_64 {
	int64 x, y, z, w;
}int4_64;












typedef struct _range_2 {
	uint32 begin; uint32 end;
}range_2;
#define RANGE_2(v) { (v), (v)};

typedef struct _range_3 {
	uint32 begin; uint32 end; uint32 num;
}range_3;
#define RANGE_3(v) { (v), (v), (v) };

typedef struct _range64_3 {
	uint64 begin; uint64 end; uint64 num;
}range64_3;
#define RANGE64_3(v) { (v), (v), (v) };


typedef struct {
	int8 s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15;
}ivec8_16;
#define DEF_IVEC8_16_INIT { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }

typedef struct {
	uint8 s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15;
}uvec8_16;
#define DEF_UVEC8_16_INIT { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }

typedef struct _Vec16 {
	float32 s0, s1, s2, s3,  s4, s5, s6, s7,  s8, s9, s10, s11,  s12, s13, s14, s15;
}vec16;
#define DEF_VEC16_INIT { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }


typedef struct _iVec32_8 {
	int32 s0, s1, s2, s3, s4, s5, s6, s7;
}ivec32_8;
typedef struct _Vec32_16 {
	int32 s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15;
}vec32_16;
#define DEF_VEC32_16_INIT { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }
typedef struct _UVec32_16 {
	uint32 s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15;
}uvec32_16;
#define DEF_VEC32_16_INIT { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }





typedef struct {
	uvec4_8* point;
	uint64	count;
}E_uvec4_8_元素指针;


typedef struct {
	vec3*	point;
	uint64	count;
}E_vec3元素指针;

typedef struct {
	vec2* point;
	uint64	count;
}E_vec2元素指针;

typedef struct {
	uint32*	point;
	uint64	count;
}E_ui32元素指针;

typedef struct {
	void*	point;
	uint64	count;
}E_序列map;

//只包含顶点的网格
typedef struct {
	vec3* m_vert;
	uvec3* m_index;
	uint32	m_vNum;
	uint32	m_iNum;
}S_三角Mesh;






typedef struct {
	float32    x;
	float32    y;
	float32    width;
	float32    height;
	float32    minDepth;
	float32    maxDepth;
} S_Viewport;


typedef struct {
	ivec2    offset;
	uvec2    extent;
} S_Rect2D;


typedef struct {
	vec2    offset;
	vec2    extent;
} S_Rect2Df;

typedef struct {
	vec2    start;
	vec2    end;
} S_Line;



typedef struct {
	vec3   begin;
	vec3   end;
}S_线段;

typedef struct {
	vec3   pos;
	vec3   size;
}S_Cube;

typedef struct {
	vec3   min;
	vec3   max;
}S_Bounding;




typedef struct {
	vec3 vert;
	vec3 normal;
}S_VN;

typedef struct {
	vec3	vert;
	uint32	color;
}S_VC;


typedef struct {
	vec3 vert;
	vec3 normal;
	vec2 UV;
}S_VNT1;

typedef struct {
	vec3 vert;
	vec3 normal;
	vec2 UV1;
	vec2 UV2;
}S_VNT2;


typedef struct {
	vec2	minXY;
	vec2	maxXY;
	vec2	val_Clamp;
	vec2*	point;
	uint32  pointNum;
}S_2D曲线数值;

typedef struct {
	vec3	minXY;
	vec3	maxXY;
	vec3	xy;
}S_3D曲线数值;






Inline uint32 f_立方根(uint32 value) {
	return uint32(exp(log(value) / 3));
}
Inline uint32 f_平方根(uint32 value) {
	return uint32(sqrtf(float32(value)));
}


